#! /bin/bash
##############################################################
##
## Name		:	u_listener
## Author	:	Bradley Atkins
## Description	:	Listener for remote job control
## Date		:	12/09/2012
## Args		:	1 - FQFN for ctrl file
##			2 - FQFN Run Log
##			3 - FQFN of tmp file
##			4 - FQFN of muse.constants
## Status	:	Reviewed 	[n]
##			Tested 		[n]
##			Released 	[n]
##############################################################

trap 'rm -rf ${PIPE} 2>/dev/null;exit' EXIT
##############################################################
##
## Name		:	log_msg
## Author	:	Bradley Atkins
## Description	:	Log a message
## Date		:	20/10/2012
## Args		:	
## Status	:	Reviewed 	[n]
##			Tested 		[n]
##			Released 	[n]
##############################################################
log_msg()
{
	echo "${1}" >> /tmp/listener.err
}
##############################################################
##
## Name		:	error_exit
## Author	:	Bradley Atkins
## Description	:	Habdle a local failure
## Date		:	20/10/2012
## Args		:	1 - Optional error msg
## Status	:	Reviewed 	[n]
##			Tested 		[n]
##			Released 	[n]
##############################################################
error_exit()
{
	log_msg "${1}"
	exit 1
}
##############################################################
##
## Name		:	read_ctl_file
## Author	:	Bradley Atkins
## Description	:	Read the listener control file
## Date		:	20/10/2012
## Args		:	
## Status	:	Reviewed 	[n]
##			Tested 		[n]
##			Released 	[n]
##############################################################
read_ctl_file()
{
	local TMPFILE=/tmp/"${0##*/}_${U_RND}"

	exec 5<> "${MSG_CTL_FILE}"
	exec 6<> "${TMPFILE}"

	#======================================
	# Read in our control file
	#======================================
	awk '{print $2}' FS=":" <&5 >&6
	exec 6>&-
	exec 6<> "${TMPFILE}"
	
	{
		set -a

		read U_MSG_NAME || error_exit "Read failed 1"		## name of remote job
		read U_MSG_PID || error_exit "Read failed 2"		## Pid of this listener
		read U_MSG_JOB_CTL_FILE || error_exit "Read failed 3"	## Job ctrl file for remote job
		read U_MSG_RUN_LOG || error_exit "Read failed 4"	## Job ctrl file for remote job
		read U_MSG_TMPFILE || error_exit "Read failed 5"	## Job ctrl file for remote job
		read U_MSG_HOST || error_exit "Read failed 6"		## Remote host
		read U_MSG_START || error_exit "Read failed 7"		## Start of listen
		read U_MSG_FINISH || error_exit "Read failed 8"		## Finish listen
		read U_MSG_PIPE || error_exit "Read failed 9"		## Name of named pipe
		read U_MSG_STATUS || error_exit "Read failed 10"	## Pending or Listening
		read U_MSG_CONSTANTS || error_exit "Read failed 11"	## muse constants
		
		set +a
	}<&6

	exec 5>&-
	exec 6>&-

	[[ -f ${TMPFILE} ]] && rm -f ${TMPFILE}
}
##############################################################
##
## Name		:	m_write_ctl_file_field
## Author	:	Bradley Atkins
## Description	:	Write data to a field in a ctl file
## Date		:	20/10/2012
## Args		:	1 - Line No
##			2 - Data
##			3 - File
## Status	:	Reviewed 	[n]
##			Tested 		[n]
##			Released 	[n]
##############################################################
m_write_ctl_file_field()
{
	[[ -w ${3} ]] || error_exit "Error: Control file not writable (${3})"

	TMP="$(sed -n ''${1}'p' "${3}" | cut -d":" -f1):${2}"
	for s in ${PIPESTATUS[@]}; do [[ $s -eq 0 ]] || error_exit "Error: Pipe failed 2 (${SCRIPT})" ; done

	awk -v ln=${1} -v lo="${TMP}" '(NR == ln){print lo;next}{print $0}' "${3}" > "${U_MSG_TMPFILE}"

	cat "${U_MSG_TMPFILE}" > "${3}"  || error_exit "Error: cp failed in m_write_ctl_file_field"

	rm -f "${U_MSG_TMPFILE}" 2>/dev/null
}

#======================================
#		START
# Validate the ctl file and then read it
#======================================
if [[ (! -s ${1}) || (! -f ${1}) || (! -r ${1}) || (! -w ${1}) ]] 
then
	exit 1
fi

#======================================
# Read our args
#======================================
MSG_CTL_FILE="${1}"
U_RND=${2}

#======================================
# Read the control file
#======================================
read_ctl_file

#======================================
# Confirm our paths were set correctly
#======================================
[[ -r "${U_MSG_CONSTANTS}" ]] || error_exit "Muse constants not found / readable (${U_MSG_CONSTANTS})"
[[ -w ${U_MSG_RUN_LOG} ]] || error_exit "Muse run log not found / writeable (${U_MSG_RUN_LOG})"
[[ -w ${U_MSG_TMPFILE} ]] || error_exit "Muse tmp file not found / writeable (${U_MSG_TMPFILE})"
[[ -w ${U_MSG_JOB_CTL_FILE} ]] || error_exit "Job ctl file not found / writeable (${U_MSG_JOB_CTL_FILE})"

source "${U_MSG_CONSTANTS}" || error_exit "Failed to source muse constants (${U_MSG_CONSTANTS})"

#======================================
# Create the pipe
#======================================
[[ -n ${U_MSG_PIPE} ]] || error_exit "Failed to set pipe name from ctl file"
export PIPE=/tmp/${U_MSG_PIPE}

[[ -p ${PIPE} ]] && error_exit "Pipe already exists (${PIPE})"
mkfifo ${PIPE}
[[ -p ${PIPE} ]] || error_exit "Pipe failed (${PIPE})"

#======================================
# Start listening
#======================================
m_write_ctl_file_field ${C_MSG_JOB_STATUS} "Listening" "${MSG_CTL_FILE}"
:> /tmp/"${U_MSG_PIPE}".listening

while true
do
        if read LINE <${PIPE} || error_exit "Pipe read failed"
	then
		## Append every line received to our ctl file
		echo "${LINE}" >> "${MSG_CTL_FILE}"

		## Set our time stamp
		TS="$(date)"

		## Recover the STATE from the message
		STATE=${LINE#*Status=}
		[[ -z ${STATE} ]] && STATE="FATAL"

		[[ ${STATE} == "FINISH" ]] && exit
		
		## Update our listener control file with the latest state
		m_write_ctl_file_field ${C_MSG_JOB_STATUS} "${STATE}" "${MSG_CTL_FILE}"
		m_write_ctl_file_field ${C_MSG_FINISH} "${TS}" "${MSG_CTL_FILE}"
		m_write_ctl_file_field ${C_MSG_ACTION} "Read" "${MSG_CTL_FILE}"
        fi
done
